<template>
	<view class="skeleton" v-if="loading">
		<u-skeleton avatar title rows="6" :loading="true" :animate="true"></u-skeleton>
	</view>

	<view class="detail" v-else>
		<view class="detail-header">
			<view class="detail-header-title">
				<text>{{ article.title }}</text>
			</view>
			<view class="detail-header-info">
				<view class="avatar">
					<u-avatar :src="article.user_id[0].avatar_file ? article.user_id[0].avatar_file.url : '/static/images/avatar.png'"></u-avatar>
				</view>
				<view class="info">
					<view class="info-name">
						<text>{{ article.user_id[0].nickname ? article.user_id[0].nickname : article.user_id[0].username }}</text>
					</view>
					<view class="info-time-local">
						<uni-dateformat class="time-format" :date="article.publish_date" format="yyyy/MM/dd" :threshold="[60000, 3600000 * 24 * 30]"></uni-dateformat>
						<text>{{ article.local }}</text>
					</view>
				</view>
			</view>
		</view>

		<view class="detail-article">
			<u-parse :content="article.content" :tag-style="style"></u-parse>
		</view>

		<view class="detail-like">
			<view class="avatar-area" v-if="article.view_count">
				<u-avatar-group :urls="avatarGroup" size="35" gap="0.4"></u-avatar-group>
			</view>
			<view class="detail-like-click" >
				<view :class="article.hasLike ? 'active' : ''" @click="handleLikeClick">
					<text class="iconfont icon-good"></text>
					<text>{{ article.like_count ? article.like_count : '' }}</text>
				</view>
			</view>
			<view class="detail-like-footer">
				<text>{{ article.view_count ? article.view_count + '人看过' : '' }}</text>
			</view>
		</view>

		<template v-if="commentLoadingState">
			<u-loading-icon></u-loading-icon>
		</template>

		<view v-if="!commentLoadingState && !this.commentList.length">
			<u-empty text="暂无评论" icon="https://cdn.uviewui.com/uview/empty/comment.png"></u-empty>
		</view>
		<view class="detail-comment">
			<Comment :items="commentList" @updateComment="updateComment"></Comment>
		</view>

		<view v-show="!popupShow" class="detail-edit-comment" @click="handleFocus">
			<view class="readOnly-input">
				<u-input class="only" line="1" style="padding: 14rpx" :placeholder="commentObj.comment" shape="circle" readonly></u-input>
			</view>

			<text class="iconfont icon-send"></text>
		</view>
		<u-popup :show="popupShow" @close="popupShow = false">
			<view class="detail-edit-comment">
				<u-input :focus="true" :cursor="10" ref="editComment" placeholder="你怎么看" shape="circle" v-model="commentObj.comment">
					<template #prefix>
						<text style="color: #888">{{ commentObj.replyUserName.length > 0 ? (commentObj.replyUserName[0].nickname || commentObj.replyUserName[0].username) : "" }}</text>
					</template>
				</u-input>
				<view class="comment-send" :class="this.commentObj.comment ? 'active' : ''" @click="addComment">发送</view>
			</view>
		</u-popup>
	</view>
</template>

<script>
import { loginPage, setStorage, getStorage, StorageObject, removeStorage, errhandler, tokenExpiredOrErrorHandler, likeClick, sortCommentData } from '@/utils/tool.js';
import Comment from '@/components/CommentItem/CommentItem.vue';
import avatarGroup from '../../uni_modules/uview-ui/libs/config/props/avatarGroup';
import { store } from '@/uni_modules/uni-id-pages/common/store.js';
const blogObj = uniCloud.importObject('blogObj', { customUI: true });
const utilObj = uniCloud.importObject('utilObj', { customUI: true });
const commentObj = uniCloud.importObject('blog-comment', { customUI: true });
export default {
	components: {
		Comment
	},
	data() {
		return {
			scrollTop: 0,
			loading: false,
			commentLoadingState: false,
			commentHasMore: true,
			article: {},
			style: {
				p: 'line-height: 1.5em; font-size:16px',
				img: 'margin: 10rpx 0'
			},
			likeClickLoading: false,
			avatarGroup: [],
			commentList: [],
			commentObj: {
				comment: '',
				commentType: 0,
				replyUserId: '',
				replyCommentId: '',
				replyUserName: '',
				ancestor_id: ''
			},
			replay_id: '',
			addCommentStatus: false,
			popupShow: false
		};
	},

	onPageScroll(e) {
		if( Math.abs(e.scrollTop - this.scrollTop) > 50){
			this.scrollTop = e.scrollTop
		}
	},
	onReachBottom() {
		const history = getStorage(StorageObject.Articleid);
		this.getCommentList(history.articleid)
	},
	onLoad() {
		this.eventChannel = this.getOpenerEventChannel();
		this.loading = true;
		uni.$once('toDetailParams', (e) => {
			const history = getStorage(StorageObject.Articleid);
			if (!history || history.articleid !== e.articleid) {
				setStorage(StorageObject.Articleid, e);
			}
		});

		setTimeout(async () => {
			await this.initData();
		}, 1000);
	},
	methods: {
		getCommentList(articleId){
			if(this.commentLoadingState) return
			if(!this.commentHasMore) return
			this.commentLoadingState = true
			
			commentObj
				.getCommentList({ articleId, skip: this.commentList.length })
				.then(res => {
					if(res.length < 10){
						this.commentHasMore = false
					} 
					this.commentList = [...this.commentList ,...res];
				})
				.catch((err) => {
					uni.showToast({
						title: '评论加载失败',
						icon: 'none'
					});
				})
				.finally(() => {
					this.commentLoadingState = false;
				});
		},
		
		async initData() {
			const that = this;
			const history = getStorage(StorageObject.Articleid);
			if (!history) {
				errhandler('加载错误');
				return;
			}
			await Promise.all([this.getData(), this.viewCountAdd(history.articleid), this.getLikeAvatarGroup()])
				.then(async (res) => {
					this.loading = false;
					that.eventChannel.emit('updateCount', { type: 'updateViewCount', value: { article_id: history.articleid, val: 1 } });
					this.getCommentList(history.articleid)
				})
				.catch(async (err) => {
					// 处理 token过期或token验证错误
					const isTokenExpiredOrError = tokenExpiredOrErrorHandler(err);
					if (isTokenExpiredOrError) return await this.initData();
					// 处理其余的服务器返回的错误
					return uni.showToast({
						title: err.message,
						icon: 'none'
					});
					setTimeout(() => {
						uni.reLaunch({
							url: '/pages/index/index'
						});
					}, 1000);
				});
		},
		async getData() {
			this.loading = true;
			const { articleid } = getStorage(StorageObject.Articleid);
			const result = await blogObj.getArticleDataById(articleid);
			this.article = result;
			return result;
		},
		async viewCountAdd(articleid) {
			const option = {
				table: 'blog',
				attr: 'view_count',
				id: articleid
			};
			return await utilObj.opration(option);
		},
		async getLikeAvatarGroup() {
			const { articleid } = getStorage(StorageObject.Articleid);
			const res = await blogObj.getArticleLikeAvatars(articleid);
			this.avatarGroup = []
			res.length &&
				res.forEach((avatar) => {
					if (avatar.user_id[0] && avatar.user_id[0].avatar_file) {
						this.avatarGroup.push(avatar.user_id[0].avatar_file.url);
					}
				});
			return res;
		},
		async handleLikeClick() {
			if (!this.currentUser.uid) {
				return uni.showToast({
					icon: 'none',
					title: this.$t('status').noLogin
				});
			}
			if (this.likeClickLoading) return;
			const { articleid } = getStorage(StorageObject.Articleid);
			this.likeClickLoading = !this.likeClickLoading;
			const isLikeBeforClick = this.article.hasLike;
			try {
				await likeClick(this.currentUser?.uid, articleid, this.article, this.updateAvatarGroup);
				this.likeClickLoading = !this.likeClickLoading;
				this.eventChannel.emit('updateCount', { type: 'updateLikeCount', value: { article_id: articleid, val: isLikeBeforClick ? -1 : 1 } });
				return;
			} catch (e) {
				return uni.showToast({
					title: e.msg,
					icon: 'none'
				});
			}
		},
		updateAvatarGroup(type) {
			function remove(avatarGroup) {
				const index = avatarGroup.findIndex((e) => e == url);
				if (index !== -1) avatarGroup.splice(index, 1);
			}
			const url = this.userInfo.avatar_file && this.userInfo.avatar_file.url;
			return url && ((type === 'add' && this.avatarGroup.push(url)) || (type === 'remove' && remove(this.avatarGroup)));
		},
		async addComment() {
			if (this.addCommentStatus) return;
			this.addCommentStatus = true;
			if (!this.commentObj.comment) return;
			const articleId = getStorage(StorageObject.Articleid).articleid;
			const userId = this.currentUser.uid;
			let obj = Object.assign(this.commentObj, { articleId }, { userId });
			try {
				if (!this.hasLogin) {
					return uni.showToast({
						title: this.$t('status').noLogin,
						icon: 'none'
					});
				}
				const res = await commentObj.addComment(obj);
				if (res.id) {
					// 以及评论更新主页评论数量
					!obj.commentType && this.eventChannel.emit('updateCount', { type: 'updateCommentCount', value: { article_id: articleId, val: 1 } });
					const newRecord = {
						_id: res.id,
						user_id: [this.userInfo],
						article_id: obj.articleId,
						comment_content: obj.comment,
						comment_date: Date.now(),
						comment_type: obj.commentType,
						like_count: 0,
						reply_comment_id: obj.replyCommentId,
						reply_user_id: obj.replyUserName,
						ancestor_id: obj.ancestor_id
					};
					// 更新视图
					if (obj.commentType == 0) {
						this.commentList.unshift(newRecord);
					} else {
						let parentIndex = this.commentList.findIndex((f) => f._id == (obj.ancestor_id || obj.replyCommentId));
						const parent = this.commentList[parentIndex];
						if (!parent.children) {
							newRecord.parent_all_replay_count = 1;
							parent.all_replay_count = 1;
							this.$set(this.commentList[parentIndex], 'children', [newRecord]);
						} else {
							let newArr = [];
							newRecord.parent_all_replay_count = parent.all_replay_count + 1;
							parent.all_reply_count += 1;
							parent.children.forEach((i) => {
								i.parent_all_reply_count += 1;
								newArr.push(i);
							});
							newArr.unshift(newRecord);
							this.$set(this.commentList[parentIndex], 'children', newArr);
						}
					}

					// 清空 commentObj
					this.commentObj = {
						comment: '',
						commentType: 0,
						replyUserId: '',
						replyCommentId: '',
						replyUserName: '',
						ancestor_id: ''
					};

					uni.showToast({
						icon: 'success'
					});
					this.handleBlur();
				}
			} catch (e) {
				uni.showToast({
					title: e.message || '评论添加失败'
				});
			} finally {
				this.addCommentStatus = false;
			}
		},
		handleFocus() {
			this.popupShow = true;
		},
		handleBlur(e) {
			this.popupShow = false;
		},
		updateComment({ type, ancestor_id, data, target, key, value }) {
			// 点击加载子评论触发
			if (type == 'updateChildList') {
				const index = this.commentList.findIndex((f) => f._id == ancestor_id);
				const newList = [...this.commentList[index].children, ...data];
				this.$set(this.commentList[index], 'children', newList);
			}
			if (type == 'updateAttr') {
				// 点击二级或多级评论时触发
				this.commentObj[key] = value._id;
				this.commentObj.replyUserId = value.user_id[0]?._id;
				this.commentObj.replyUserName = value.user_id;
				if (value.comment_type == 0) {
					this.commentObj.commentType = 1;
					this.commentObj.ancestor_id = value._id;
				} else {
					this.commentObj.commentType = 2;
					this.commentObj.ancestor_id = value.ancestor_id;
				}
				this.handleFocus();
			}
		}
	},
	onHide() {
		// removeStorage(StorageObject.Articleid);
	},
	onUnload() {
		// removeStorage(StorageObject.Articleid);
	},
	computed: {
		userInfo() {
			return store.userInfo;
		},
		hasLogin() {
			return store.hasLogin;
		},
		currentUser() {
			return uniCloud.getCurrentUserInfo();
		}
	}
};
</script>

<style lang="scss"></style>
